import { observable, action, computed } from 'mobx';
import Base from 'stores/models/core/base';
import { findDeepestCurrent } from 'common/utils/store';

/**
 * BaseWithList
 * 基于 Base 类扩展，带 list 属性及相关 action。
 */
export default class BaseWithList extends Base {

  @observable list = [];

  @observable current = null;

  // 获取最深级的 current 对象，用于渲染 config 区域 和 确定路由
  @computed get deepCurrent() {
    return findDeepestCurrent(this);
  }

  // 是否有多个选中
  @computed get hasMultiCurrents() {
    const multiCurrents = this.list.filter(item => {
      return item.selected === true;
    });
    return multiCurrents.length > 1;
  }

  // 返回一个倒序的list
  @computed get reverseList() {
    return this.list.reverse();
  }

  @action insert(item, fromIndex = -1) {
    // item may be a page
    item.parent = this;
    // item.parent
    if (fromIndex === -1) {
      // this.list = [...this.list].concat(item);
      this.list.push(item);
    } else {
      this.list.splice(fromIndex + 1, 0, item);
    }
    this.select(item);
  }

  /**
   * 选中一个子元素
   * @param item
   * @param multi 多选参数
   */
  @action select(item, multi = false) {
    if (multi === false) {
      this.unSelect();
    }
    this.current = item;
    this.current.selected = true;
  }

  /**
   * 取消当前选中的子元素
   */
  @action unSelect() {
    this.current = null;
    if (this.list.length) {
      this.list.forEach(item => {
        item.selected = false;
      });
    }
  }

  /**
   * 选中自己
   * @param multi
   */
  @action selectSelf(multi = false) {
    if (this.parent) {
      this.unSelect();
      this.parent.select(this, multi);
    }
  }

  /**
   * 取消选中自己
   */
  @action unSelectSelf() {
    if (this.parent && this.parent.current && this.parent.current === this) {
      this.parent.current = null;
    } else {
      this.selected = false;
    }
  }

  @action remove(item) {
    this.list.remove(item);
  }

  @action removeSelf() {
    if (this.parent) {
      this.unSelectSelf();
      this.parent.remove(this);
    }
  }

  /**
   * 使用新的List 替换当前的这个list
   * @param newList
   */
  @action replace(newList) {
    this.list = newList;
  }

}
